/*
 * util.c
 *
 * Utility routines for game implementation.
 *
 * Copyright (c) 2010, Alan Green.
 * Contactable at <firstname>.<lastname>@gmail.com
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 	1.	Redistributions of source code must retain the above copyright
 * 		notice, this list of conditions and the following disclaimer.
 * 	2.	Redistributions in binary form must reproduce the above copyright
 * 		notice, this list of conditions and the following disclaimer in the
 * 		documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * ===============================================
 */

#include "util.h"
#include "display.h"

uint8_t BITS[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

void fill_display_ram(uint8_t value) {
    uint8_t *p = display_ram;
    *(p++) = value; // 0
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 5
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 10
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 15
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 20
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 25
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 30
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // 35
    *(p++) = value;
    *(p++) = value;
    *(p++) = value;
    *(p++) = value; // display_ram_end - 1  (display_ram + 39)
}

// Reads a pot
uint16_t read_pot(uint8_t pin) {
    // Select pot
    ADMUX = (ADMUX & 0xf0) | pin;
    // start conversion, clear done flag
    ADCSRA = (ADCSRA & (_BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0)))
            | _BV(ADSC) | _BV(ADIF);
    while (!(ADCSRA & _BV(ADIF))) {
        //wait for conversion to complete
    }
    uint16_t val = ADCL;
    val |= ADCH << 8;
    return val;
}


static uint16_t remaining_ticks;

// Starts sounding a tone
void tone_start(uint8_t wave_len, uint16_t ticks) {
    OCR2A = wave_len;
    OCR2B = wave_len >> 2;
    TCNT2 = 0x0;
    TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20);
    remaining_ticks = ticks;
    DDRD |= _BV(PD3);
}

// Process a timer tick
void tone_tick(void) {
    if (remaining_ticks == 0) {
        return;
    }
    remaining_ticks -= 1;
    if (remaining_ticks == 0) {
        DDRD &= ~_BV(PD3);
        TCCR2B = 0; // Stop tone
    }
}
